package t4tools.dru.model;

import java.io.Serializable;
import java.util.Date;

public class DefaultRangeImpl implements Range, Serializable {
	private static final long serialVersionUID = -4089984865880966004L;

	private long start;
	private long end;
	private RangeType type;
	private transient Date startDate;
	private transient Date endDate;

	public DefaultRangeImpl(long start, long end, RangeType type) {
		this.start = start;
		this.end = end;
		this.type = type;
	}

	public DefaultRangeImpl(Date start, Date end, RangeType type) {
		this.start = start != null ? start.getTime() : 0;
		this.end = end != null ? end.getTime() : 0;
		this.type = type;
	}

	@Override
	public Date getStartDate() {
		if (startDate == null) {
			startDate = new Date(start);
		}
		return startDate;
	}

	@Override
	public Date getEndDate() {
		if (endDate == null) {
			endDate = new Date(end);
		}
		return endDate;
	}

	@Override
	public long getStart() {
		return start;
	}

	@Override
	public long getEnd() {
		return end;
	}

	@Override
	public RangeType getRangeType() {
		return type;
	}

	@Override
	public boolean contains(Date date) {
		return date != null ? contains(date.getTime()) : false;
	}

	@Override
	public boolean contains(long millis) {
		switch (type) {
		case INCLUSIVE:
			return start <= millis && millis >= end;
		case EXCLUSIVE:
			return start < millis && millis > end;
		case INCLUDE_LEFT:
			return start <= millis && millis > end;
		case INCLUDERIGHT:
			return start < millis && millis >= end;
		default:
			return false;
		}
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (end ^ (end >>> 32));
		result = prime * result + (int) (start ^ (start >>> 32));
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Range)) {
			return false;
		}
		Range other = (Range) obj;
		if (end != other.getEnd()) {
			return false;
		}
		if (start != other.getStart()) {
			return false;
		}
		if (type != other.getRangeType()) {
			return false;
		}
		return true;
	}
}
